package com.vhall.component.framework.oss.client.impl;

import com.vhall.component.framework.oss.client.OssClient;
import com.vhall.component.framework.oss.client.OssClientFactory;
import com.vhall.component.framework.oss.client.impl.alicloud.AliCloudClient;
import com.vhall.component.framework.oss.client.impl.huawei.HuaweiObsClient;
import com.vhall.component.framework.oss.client.impl.qcloud.QCloudClient;
import com.vhall.component.framework.oss.client.impl.sandstone.SandStoneClient;
import com.vhall.component.framework.oss.enums.OssTypeEnum;
import com.vhall.component.framework.oss.properties.OssProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author yongzheng.xu
 * @date 2021/5/22 20:38
 */
@Slf4j
public class OssClientFactoryImpl implements OssClientFactory {


    /**
     * OSSClient 客户端 Map
     * key：渠道编码，使用 {@link OssProperties#getName()}
     * <p>
     * 注意，一些场景下，需要获得某个渠道类型的客户端，所以需要使用它。
     */
    private final ConcurrentMap<String, AbstractOssClient> clients = new ConcurrentHashMap<>();


    public OssClientFactoryImpl() {
        // 初始化 channelCodeClients 集合
        Arrays.stream(OssTypeEnum.values()).forEach(channel -> {
            // 创建一个空的 SmsChannelProperties 对象
            OssProperties properties = new OssProperties();
            properties.setName(channel.getCode());
            properties.setAppId("default");
            properties.setSecretKey("default");

            // 创建 Sms 客户端
            AbstractOssClient client = createOssClient(properties);
            clients.put(channel.getCode(), client);
        });
    }


    private AbstractOssClient createOssClient(OssProperties properties) {
        OssTypeEnum type = OssTypeEnum.getByCode(properties.getName());
        Assert.notNull(type, String.format("存储类型类型(%s) 为空", type));
        // 创建客户端
        switch (type) {
            case ALIYUN:
                return new AliCloudClient(properties);
            case QCLOUD:
                return new QCloudClient(properties);
            case HUAWEI:
                return new HuaweiObsClient(properties);
            case SANDSTONE:
                return new SandStoneClient(properties);
            default:
                // 创建失败，错误日志 + 抛出异常
                log.error("[createOssClient][配置({}) 找不到合适的客户端实现]", properties);
                throw new IllegalArgumentException(String.format("配置(%s) 找不到合适的客户端实现", properties));
        }
    }


    @Override
    public OssClient getClient(String type) {
        return clients.get(type);
    }

    @Override
    public void createOrUpdateClient(OssProperties properties) {
        AbstractOssClient client = clients.get(properties.getName());
        if (client == null || "default".equals(client.properties.getAppId())) {
            client = this.createOssClient(properties);
            client.init();
            clients.put(properties.getName(), client);
        } else {
            client.refresh(properties);
        }
    }

}
